/*
 * AffineRansac.h
 *
 *  Created on: Aug 31, 2012
 *      Author: alberto
 *
 *  Implementa RANSAC para solucionar a transformação affine entre duas imagens A e B, usando a função getAffineTransform
 *  da biblioteca OpenCV. O processo é simples: Como entrada, temos os keypoints da imagem A e da imagem B, e os matches
 *  entre esses keypoints, seguindo-se então os seguintes passos:
 *  1 - Escolhe-se 3 matches (a função que estima a transformação affine precisa de 3 matches) iniciais entre as imagens.
 *      A escolha desses pontos pode ser feita segundo qualquer critério, inclusive aleatório. Aqui, para escolha dos
 *      pontos, primeiro ordena-se os matches de acordo com suas distâncias, escolhendo-se então os 3 de menor distância.
 *
 *  2 - Estima-se a matriz de transformação affine de A para B usando-se a função cv::getAffineTransform com os três pontos
 *      escolhidos
 *
 *  3 - Aplica-se a transformação affine estimada nos keypoints de A.
 *
 *  4 - Compara-se o resultado da transfomação affine dos keypoints de A com os keypoints de B. Se a transformação for
 *      boa, esperamos que a maioria dos pontos transformados de A estejam à pouca distância dos de B. Definimos assim
 *      os 'inliers' e 'outliers' para essa transformação.
 *
 *  5 - Caso a porcentagem de inliers seja grande o suficiente, para. Senão, escolhemos três pontos aleatórios dos inliers
 *      e repetimos os passos de 2 a 5
 */

#ifndef AFFINERANSAC_H_
#define AFFINERANSAC_H_

#include "Utilities.h"

#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/features2d/features2d.hpp>
#include<vector>
#include<cmath>

using namespace std;
using namespace cv;

class AffineRansac {
public:
	AffineRansac(const vector<KeyPoint>& kA, const vector<KeyPoint>& kB, const vector<DMatch>& m);
	virtual ~AffineRansac();

	void setDelta(double d);
	Mat solve();
	double testTransform(const Mat& affineTransform);
    static int calculateIterations(double threshold, int samples, double outlierRate);

private:
	Mat pointsA;
	Mat pointsB;
	vector<DMatch> matches;
	int iterations;
	double delta;


};

#endif /* AFFINERANSAC_H_ */
